﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    public class TReceivingGoodsDetailRepository : BaseRepository<TReceivingGoodsDetail>, ITReceivingGoodsDetailRepository
    {
        IBarCodeRuleRepository barCodeRuleRepository {  get; set; }
        public TReceivingGoodsDetailRepository(DFGK_DB context, IMapper mapper, IBarCodeRuleRepository barCodeRuleRepository) : base(context, mapper)
        {
            this.barCodeRuleRepository = barCodeRuleRepository;
        }

        public bool AddReceivingGoodsDetail(List<TReceivingGoodsDetail> receivingGoodsDetails)
        {
            //使用事务的原子性
            using (var trans = Context.Database.BeginTransaction())
            {
                try
                {
                    if (receivingGoodsDetails.Count > 0)
                    {
                        foreach (var item in receivingGoodsDetails)
                        {
                            Context.TReceivingGoodsDetails.Add(item);
                            Context.SaveChanges();
                        }
                    }
                    Context.SaveChanges();
                    //提交事务
                    trans.Commit();
                    return true;
                }
                catch (Exception)
                {
                    //事务回滚
                    trans.Rollback();
                    throw;
                }
            }


        }

        public List<TReceivingGoodsDetail> GetReceivingGoodsDetailList(int orderDetailid)
        {
            var res = Context.TReceivingGoodsDetails.Where(r => r.OrderDetailId == orderDetailid).ToList();
            if (res.Count() > 0)
            {
                return res;
            }
            return null;
        }


        /// <summary>
        /// 采购收货单接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddTPurchaseReceipt(PurchaseReceiptDto dto, out string message)
        {
            message = "";
            var receivingBillsDetails = new List<TReceivingBillDetail>();
            var supplierList = Context.TSuppliers.Where(x => x.Code == dto.SupplierCode).ToList();
            if (!supplierList.Any())
            {
                //直接返回报错
                message = "未查询到供应商编码为" + dto.SupplierCode + "的相关信息,请检查信息是否添加正确";
                return false;
            }

            var receivingBillList = Context.TReceivingBillDetails.Where(x => x.OrderSn == dto.OrderSn).ToList();
            if (receivingBillList.Count() > 0)
            {
                message = "单号重复:" + dto.OrderSn;
                return false;
            }

            TWarehouse warehouse = new TWarehouse();

            if (dto.Floor == 1)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "1楼立体库").FirstOrDefault();

            }
            else if (dto.Floor == 2)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "2楼立体库").FirstOrDefault();
            }
            else
            {
                message = "楼层输入错误";
                return false;
            }
            var receivingBills = new TReceivingBill
            {
                BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                OrderSn = dto.OrderSn,
                //SupplierId = dto.SupplierId,
                SupplierName = dto.SupplierName,
                SupplierCode = dto.SupplierCode,
                Status = 0,
                BillType = dto.BillType,
                CreateDate = DateTime.Now,
                BeginDate = DateTime.Now,
                //EndDate = DateTime.Now,
                //采购订单号
                RefSn = dto.PurOrderLineNo,
                TotalQty = dto.ChildList.Sum(x => x.Qty),
                WarehouseId = warehouse.Id == 0 ? 0 : warehouse.Id,
                WarehouseCode = warehouse.Code == null ? "" : warehouse.Code,
                WarehouseName = warehouse.Name == null ? "" : warehouse.Name,

            };
            Context.TReceivingBills.Add(receivingBills);
            if (Context.SaveChanges() <= 0)
            {
                message = "添加收货单失败,单号:" + dto.OrderSn + ",业务类型为:采购收货单";
                return false;
            }


            foreach (var item in dto.ChildList)
            {
                var DetailId = Context.TReceivingBills.Where(x => x.BillNo == dto.OrderSn);
                if (DetailId.Count() <= 0)
                {
                    message = "查询收货单失败,单号:" + dto.OrderSn + ",业务类型为:采购收货单";
                    return false;
                }
                var materialList = Context.TMaterial.Where(x => x.Code == item.TMaterialCode);
                if (materialList.Count() <= 0)
                {
                    message = "暂时没有物料编码为:" + item.TMaterialCode + "的物料";
                    return false;
                }
                int billId = DetailId.First().Id;
                var receivingBill = new TReceivingBillDetail
                {
                    OrderSn = dto.OrderSn,
                    PompanyCode = dto.PompanyCode,
                    PompanyName = dto.PompanyName,
                    BillType = dto.BillType,
                    BillNo = dto.OrderSn,
                    BillId = billId,
                    MoveType = dto.MoveType,
                    PurOrderLineNo = dto.PurOrderLineNo,
                    DocumentDate = dto.DocumentDate,
                    SupplierCode = dto.SupplierCode,
                    SupplierName = dto.SupplierName,
                    IineItem = item.IineItem,
                    TMaterialCode = item.TMaterialCode,
                    TMaterialName = item.TMaterialName,
                    MaterialId = materialList.First().Id,
                    MaterialName = item.TMaterialName,
                    MaterialCode = item.TMaterialCode,
                    MaterialTypeName = item.TMaterialName,
                    ModelSpec = item.ModelSpec,
                    Qty = item.Qty,
                    ExpectedTime = item.ExpectedTime,
                    CustomerName = item.CustomerName,
                    CustomerCode = item.CustomerCode,
                    FactoryCode = item.FactoryCode,
                    FactoryName = item.FactoryName,
                    Status = 0,
                    FlowPathType = 1
                };

                receivingBillsDetails.Add(receivingBill);
            }

            Context.TReceivingBillDetails.AddRange(receivingBillsDetails);
            if (Context.SaveChanges() > 0)
            {
                return true;
            }
            message = "添加收货单失败,单号:" + dto.OrderSn + ",业务类型为:采购收货单";
            return false;
        }

        /// <summary>
        /// 生产订单接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddProductionOrder(ProductionOrderDto dto, out string message)
        {
            message = "";

            var receivingBillList = Context.TReceivingBillDetails.Where(x => x.OrderSn == dto.OrderSn).ToList();
            if (receivingBillList.Count() > 0)
            {
                message = "单号重复:" + dto.OrderSn;
                return false;
            }
            TWarehouse warehouse = new TWarehouse();

            if (dto.Floor == 1)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "1楼立体库").FirstOrDefault();

            }
            else if (dto.Floor == 2)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "2楼立体库").FirstOrDefault();
            }
            else
            {
                message = "楼层输入错误";
                return false;
            }

            var receivingBill = new TReceivingBill()
            {
                BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                BillType = dto.BillType,
                Status = 0,
                CreateDate = DateTime.Now,
                BeginDate = DateTime.Now,
                TotalQty = dto.ReceivedQty,
                WarehouseId = warehouse.Id,
                WarehouseCode = warehouse.Code,
                WarehouseName = warehouse.Name,
                OrderSn = dto.OrderSn,

            };
            Context.TReceivingBills.Add(receivingBill);
            if (Context.SaveChanges() <= 0)
            {
                message = "添加收货单失败,单号:" + dto.OrderSn + ",业务类型为:生产订单";
                return false;
            }
            var receivingList = Context.TReceivingBills.Where(x => x.OrderSn == dto.OrderSn).ToList();
            if (receivingList.Count <= 0)
            {
                message = "查询收货单号失败,单号" + dto.OrderSn + ",业务类型为:生产订单";
                return false;
            }
            var materialList = Context.TMaterial.Where(x => x.Code == dto.TMaterialCode).ToList();
            if (materialList.Count <= 0)
            {
                message = "暂无此物料:" + dto.TMaterialName;
                return false;
            }
            var receivingBillDtails = new TReceivingBillDetail
            {
                BillId = receivingList.First().Id,
                BillLineNo = dto.OrderSn,
                Status = 0,
                OrderSn = dto.OrderSn,
                BillType = dto.BillType,
                BillNo = dto.OrderSn,
                PompanyCode = dto.PompanyCode,
                PompanyName = dto.PompanyName,
                MaterialId = materialList.FirstOrDefault().Id,
                TMaterialCode = dto.TMaterialCode,
                MaterialCode = dto.TMaterialCode,
                TMaterialName = dto.TMaterialName,
                MaterialName = dto.TMaterialName,
                Qty = dto.ReceivedQty,
                UnitName = dto.UnitName,
                UnitCode = dto.UnitCode,
                PlanStartTime = dto.PlanStartTime,
                PlanEndTime = dto.PlanEndTime,
                FlowPathType = 2
            };

            Context.TReceivingBillDetails.Add(receivingBillDtails);
            if (Context.SaveChanges() <= 0)
            {
                message = "添加收货单明细表失败,单号:" + dto.OrderSn + ",业务类型为:生产订单";
                return false;
            }
            return true;
        }

        /// <summary>
        /// 生产退料单接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddProductionMaterilas(ProductionMaterilasDto dto, out string message)
        {
            using (var trans = Context.Database.BeginTransaction())
            {
                message = "";

                var receivingBillList = Context.TReceivingBills.Where(x => x.OrderSn == dto.OrderSn).ToList();
                if (receivingBillList.Count() > 0)
                {
                    trans.Rollback();
                    message = "单号重复:" + dto.OrderSn;
                    return false;
                }
                var receivingBillsDetail = new List<TReceivingBillDetail>();
                decimal totalQty = 0;
                foreach (var item in dto.ChildList)
                {
                    totalQty += item.Qty;
                }
                TWarehouse warehouse = new TWarehouse();

                if (dto.Floor == 1)
                {
                    warehouse = Context.TWarehouses.Where(x => x.Name == "1楼立体库").FirstOrDefault();

                }
                else if (dto.Floor == 2)
                {
                    warehouse = Context.TWarehouses.Where(x => x.Name == "2楼立体库").FirstOrDefault();
                }
                else
                {
                    trans.Rollback();
                    message = "楼层输入错误";
                    return false;
                }

                var agvPoint = Context.TAGVBinDingPoint.FirstOrDefault(x => x.TaskType == 1036);
                if (agvPoint == null)
                {
                    trans.Rollback();
                    message = "暂无此业务类型相关的AGV路线";
                    return false;
                }
                var receiving = new TReceivingBill()
                {
                    BillType = 1036,
                    BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                    OrderSn = dto.OrderSn,
                    PompanyCode = dto.PompanyCode,
                    PompanyName = dto.PompanyName,
                    ProductName = dto.ProductName,
                    ProductCode = dto.ProductCode,
                    CreateDate = DateTime.Now,
                    Status = 0,
                    BeginDate = DateTime.Now,
                    WarehouseId = warehouse.Id,
                    WarehouseCode = warehouse.Code,
                    WarehouseName = warehouse.Name,
                    AGVStartPoint = dto.SourceLocation,
                    AGVEndPoint = agvPoint.AGVEndPoint,
                    PurOrderLineNo = dto.WorkOrderSn,
                    //EndDate = DateTime.Now,
                    //RefSn = dto.OrderSn,
                    TotalQty = totalQty,
                };
                Context.TReceivingBills.Add(receiving);
                if (Context.SaveChanges() <= 0)
                {
                    trans.Rollback();
                    message = "新增收货单信息失败，单号:" + dto.OrderSn + ",业务类型为:生产退料";
                    return false;
                }
                var receList = Context.TReceivingBills.FirstOrDefault(x => x.BillNo == dto.OrderSn);
                if (receList == null)
                {
                    trans.Rollback();
                    message = "未查询到入库单";
                    return false;
                }


                foreach (var item in dto.ChildList)
                {
                    var materialList = Context.TMaterial.FirstOrDefault(x => x.Code == item.TMaterialCode);
                    if (materialList == null)
                    {
                        trans.Rollback();
                        message = "暂无此物料" + item.TMaterialName;
                        return false;
                    }
                    var receivingBill = new TReceivingBillDetail
                    {
                        BillId = receList.Id,
                        BatchNo = item.BatchNo,
                        Weight = item.Weight,
                        WeightUnitName = item.WeightUnitName,
                        OrderSn = dto.OrderSn,
                        PompanyCode = dto.PompanyCode,
                        PompanyName = dto.PompanyName,
                        ProductName = dto.ProductName,
                        ProductCode = dto.ProductCode,
                        IineItem = item.IineItem,
                        MaterialId = materialList.Id,
                        TMaterialCode = item.TMaterialCode,
                        MaterialCode = item.TMaterialCode,
                        TMaterialName = item.TMaterialName,
                        MaterialName = item.TMaterialName,
                        ModelSpec = item.ModelSpec,
                        Qty = item.Qty,
                        UnitName = item.UnitName,
                        UnitCode = item.UnitCode,
                        FlowPathType = 3,
                        Status = 0,
                        
                    };

                    receivingBillsDetail.Add(receivingBill);
                }

                Context.TReceivingBillDetails.AddRange(receivingBillsDetail);
                if (Context.SaveChanges() > 0)
                {
                    trans.Commit();
                    return true;
                }
                message = "添加明细失败";
                trans.Rollback();
                return false;
            }
        }

        /// <summary>
        /// 销售订单退货接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddSalesOrderReturn(SalesOrderReturnDto dto, out string message)
        {
            message = "";


            var receivingBillList = Context.TReceivingBillDetails.Where(x => x.OrderSn == dto.OrderSn).ToList();
            if (receivingBillList.Count() > 0)
            {
                message = "单号重复:" + dto.OrderSn;
                return false;
            }
            TWarehouse warehouse = new TWarehouse();

            if (dto.Floor == 1)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "1楼立体库").FirstOrDefault();

            }
            else if (dto.Floor == 2)
            {
                warehouse = Context.TWarehouses.Where(x => x.Name == "2楼立体库").FirstOrDefault();
            }
            else
            {
                message = "楼层输入错误";
                return false;
            }
            var receivingBillsDetail = new List<TReceivingBillDetail>();
            var receivingBill = new TReceivingBill()
            {
                BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                OrderSn = dto.OrderSn,
                PompanyCode = dto.PompanyCode,
                PompanyName = dto.PompanyName,
                RefSn = dto.SafeOrderSn,
                ReturnDateTime = dto.ReturnDateTime,
                CustomerCode = dto.CustomerCode,
                CustomerName = dto.CustomerName,
                Status = 0,
                CreateDate = DateTime.Now,
                BeginDate = DateTime.Now,
                WarehouseId = warehouse.Id,
                WarehouseCode = warehouse.Code,
                WarehouseName = warehouse.Name,
                //EndDate = DateTime.Now,
            };
            Context.TReceivingBills.Add(receivingBill);
            if (Context.SaveChanges() <= 0)
            {
                message = "新增收货单信息失败，单号:" + dto.OrderSn + ",业务类型为:销售订单退货";
                return false;
            }

            foreach (var item in dto.ChildList)
            {
                var receivingBillDetail = new TReceivingBillDetail
                {
                    OrderSn = dto.OrderSn,
                    BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                    PompanyCode = dto.PompanyCode,
                    PompanyName = dto.PompanyName,
                    SafeOrderSn = dto.SafeOrderSn,
                    ReturnDateTime = dto.ReturnDateTime,
                    CustomerCode = dto.CustomerCode,
                    CustomerName = dto.CustomerName,
                    IineItem = item.IineItem,
                    SaleIineItem = item.SaleIineItem,
                    TMaterialCode = item.TMaterialCode,
                    TMaterialName = item.TMaterialName,
                    ModelSpec = item.ModelSpec,
                    Qty = item.Qty,
                    UnitName = item.UnitName,
                    UnitCode = item.UnitCode,
                    FlowPathType = 4,
                    Status = 0
                };

                receivingBillsDetail.Add(receivingBillDetail);
            }

            Context.TReceivingBillDetails.AddRange(receivingBillsDetail);
            if (Context.SaveChanges() <= 0)
            {
                message = "新增收货单信息失败，单号:" + dto.OrderSn + ",业务类型为:销售订单退货";
                return false;
            }
            return true;
        }


        /// <summary>
        /// 生产入库单接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddProduceReceiving(ProduceReceivingDto dto, out string message)
        {
            message = "";

            using (var trans = Context.Database.BeginTransaction())
            {
                var receivingBillList = Context.TReceivingBills.Where(x => x.OrderSn == dto.OrderSn).ToList();
                if (receivingBillList.Count() > 0)
                {
                    trans.Rollback();
                    message = "单号重复:" + dto.OrderSn;
                    return false;
                }

                TWarehouse warehouse = new TWarehouse();

                if (dto.Floor == 1)
                {
                    warehouse = Context.TWarehouses.Where(x => x.Name == "1楼立体库").FirstOrDefault();

                }
                else if (dto.Floor == 2)
                {
                    warehouse = Context.TWarehouses.Where(x => x.Name == "2楼立体库").FirstOrDefault();
                }
                else
                {
                    trans.Rollback();
                    message = "楼层输入错误";
                    return false;
                }
                var agvModel = Context.TAGVBinDingPoint.FirstOrDefault(x => x.TaskType == 1035);
                if (agvModel == null)
                {
                    trans.Rollback();
                    message = "暂无业务类型: 生产订单相关的AGV路线";
                    return false;
                }

                decimal totalQty = 0;
                foreach (var item in dto.ChildList)
                {
                    totalQty += item.ReceivingQty;
                }
                var receivingBillsDetail = new List<TReceivingBillDetail>();
                var receivingBill = new TReceivingBill()
                {
                    BillType = 1035,
                    BillNo = barCodeRuleRepository.GetBarCodeSample(1),
                    OrderSn = dto.OrderSn,
                    AGVStartPoint = dto.Sourcelocation,
                    AGVEndPoint = agvModel.AGVEndPoint,
                    WorkOrderSn = dto.WorkOrderSn,
                    ProductionOrderSn = dto.ProductionOrderSn,
                    Status = 0,
                    CreateDate = DateTime.Now,
                    BeginDate = DateTime.Now,
                    WarehouseId = warehouse.Id,
                    WarehouseCode = warehouse.Code,
                    WarehouseName = warehouse.Name,
                    TotalQty = totalQty,
                    ReceivedQTY = 0,
                    ReceivedQty = dto.ChildList.Sum(x => x.ReceivingQty)
                    //EndDate = DateTime.Now,
                };
                Context.TReceivingBills.Add(receivingBill);
                if (Context.SaveChanges() <= 0)
                {
                    trans.Rollback();
                    message = "新增收货单信息失败，单号:" + dto.OrderSn + ",业务类型为:销售订单退货";
                    return false;
                }

                var receivingList = Context.TReceivingBills.FirstOrDefault(x => x.BillNo == dto.OrderSn);


                foreach (var item in dto.ChildList)
                {
                    var materialModel = Context.TMaterial.FirstOrDefault(x => x.Code == item.TMaterialCode);
                    if (materialModel == null)
                    {
                        trans.Rollback();
                        message = "暂无此物料" + item.TMaterialName;
                        return false;
                    }
                    var receivingBillDetail = new TReceivingBillDetail
                    {
                        BillId = receivingList.Id,
                        OrderSn = dto.OrderSn,
                        BillNo = dto.OrderSn,
                        IineItem = item.IineItem,
                        MaterialId = materialModel.Id,
                        TMaterialCode = item.TMaterialCode,
                        TMaterialName = item.TMaterialName,
                        MaterialCode = item.TMaterialCode,
                        MaterialName = item.TMaterialName,
                        ModelSpec = item.ModelSpec,
                        BatchNo = item.BatchNo,
                        Qty = item.ReceivingQty,
                        Weight = item.Weight,
                        WeightUnitName = item.WeightUnitName,
                        UnitName = item.UnitName,
                        FlowPathType = 4,
                        Status = 0
                    };

                    receivingBillsDetail.Add(receivingBillDetail);
                }

                Context.TReceivingBillDetails.AddRange(receivingBillsDetail);
                if (Context.SaveChanges() <= 0)
                {
                    trans.Rollback();
                    message = "新增收货单信息失败，单号:" + dto.OrderSn + ",业务类型为:销售订单退货";
                    return false;
                }
                trans.Commit();
                return true;
            }
        }



        public async Task<bool> PostMESReceiving(MESReceivingDto dto)
        {
            // 使用 HttpClient 来发送 HTTP 请求
            using (HttpClient client = new HttpClient())
            {
                try
                {

                    //接口地址(待确认)
                    string apiUrl = "127.0.0.1:8080/dts/wmsapi/warehousing/insert";
                    string jsonData = JsonConvert.SerializeObject(dto);
                    StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                    // 发送 POST 请求到指定的 API 地址
                    HttpResponseMessage response = await client.PostAsync(apiUrl, content);

                    if (response.IsSuccessStatusCode)
                    {
                        string responseBody = await response.Content.ReadAsStringAsync();
                        Console.WriteLine("Response: " + responseBody);
                        return true;
                    }
                    else
                    {
                        Console.WriteLine("未能调用API。状态代码: " + response.StatusCode);
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("出现错误: " + ex.Message);
                    return false;
                }
            }
        }
    }
}
